﻿using Com.Lancetinc.Evs.Events;
using Com.Lancetinc.Evs.Helpers;
using Com.Lancetinc.Evs.Reports;
using Com.Lancetinc.Evs.Services;
using Com.Lancetinc.Evs.ViewModels;
using Prism.Commands;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media.Imaging;

namespace Com.Lancetinc.Evs.Controls
{
    /// <summary>
    /// 截屏列表
    /// </summary>
    public partial class CapturedImageUserControl
    {
        private string mCurrentImageName;
        private ExperInfo mExper;
        private ObservableCollection<ImageViewModel> mImages;
        /** 图片数量改变(被删除) */
        public event EventHandler<CaptureImageChangedEventArgs> ImageCountChanged;

        public event EventHandler CloseClicked;

        public bool IsHover { get; private set; } = false;
        /// <summary>
        /// 是否显示关闭
        /// </summary>
        public bool IsShowClose
        {
            get => BtnClose.Visibility == Visibility.Visible;
            set
            {
                if (value)
                    BtnClose.Visibility = Visibility.Visible;
                else
                    BtnClose.Visibility = Visibility.Collapsed;
            }
        }

        /// <summary>
        /// 是否显示头部(标题+关闭按钮)
        /// </summary>
        public bool IsShowHeader
        {
            get => GridHeader.Visibility == Visibility.Visible;
            set
            {
                if (value)
                    GridHeader.Visibility = Visibility.Visible;
                else
                    GridHeader.Visibility = Visibility.Collapsed;
            }
        }

        public UserControlUsage Usage { get; set; } = UserControlUsage.None;

        public DelegateCommand<ImageViewModel> DeleteImageCommand { get; }
        public CapturedImageUserControl()
        {
            InitializeComponent();
            this.MouseEnter += CapturedImageUserControl_MouseEnter;
            this.MouseLeave += CapturedImageUserControl_MouseLeave;
            DeleteImageCommand = new DelegateCommand<ImageViewModel>(ExecuteDeleteImage);
        }

        private void CapturedImageUserControl_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            IsHover = false;
        }

        private void CapturedImageUserControl_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            IsHover = true;
        }

        public void SetExper(ExperInfo exper)
        {
            if (mExper == exper)
                return;

            if (mExper != null)
            {
                mExper.Images.CollectionChanged -= Images_CollectionChanged;
            }

            mExper = exper;
            mImages = null;
            if (exper != null)
            {
                exper.Images.CollectionChanged += Images_CollectionChanged;
                BuildImages(false);
            }

            if (Usage == UserControlUsage.Report)
            {
                GongSolutions.Wpf.DragDrop.DragDrop.SetIsDragSource(IcImages, true);
            }
        }

        public void ShowImage(string imageName)
        {
            imageName ??= string.Empty;
            mCurrentImageName = imageName;
            CtrlCurrentImageName.Text = imageName;
            bool hasImg = false;
            if (!string.IsNullOrEmpty(imageName))
            {
                var imgPath = mExper.GetImageFullPath(imageName);
                if (File.Exists(imgPath))
                {
                    var bitmap = new BitmapImage();
                    bitmap.BeginInit();
                    bitmap.UriSource = new Uri(TempDirHelper.GetTempImageFilePath(imgPath));
                    bitmap.EndInit();
                    CurrentImage.Source = bitmap;
                    hasImg = true;
                }
            }
            else if (CurrentImage.Source != null)
            {
                CurrentImage.Source = null;
            }

            if (Usage == UserControlUsage.Report)
                return; // 报告的时候不必显示预览

            PanelImgPreview.Visibility = hasImg ? Visibility.Visible : Visibility.Collapsed;
        }

        private void Images_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            BuildImages(true);

            if (e.Action != NotifyCollectionChangedAction.Add)
            {
                // 只通知删除事件
                ImageCountChanged?.Invoke(this, new CaptureImageChangedEventArgs(this.mExper, 1));
            }
        }

        private void ThisControl_Unloaded(object sender, RoutedEventArgs e)
        {
            if (mExper != null)
            {
                mExper.Images.CollectionChanged -= Images_CollectionChanged;
            }
        }

        private async void ExecuteDeleteImage(ImageViewModel vm)
        {
            var exper = mExper.Exper.Exper;
            var reportImages = ReportHelper.SplitReportImages(exper.ReportImages).ToList();
            if (reportImages.Contains(vm.Name))
            {
                // 该图片已被报告使用，不能删除
                MessageHelper.ShowWarningByMsgId("PicturesUsedByReport");
                return;
            }
            // 确定要删除截图 [{0}] 吗？
            var msg = I18nHelper.Default.GetMessageWithArgs("CapturedImageUserControl.ConfirmDeleteSingleImage", vm.Name);
            var dlgResult = await MessageHelper.ShowYesNoAsync(msg);

            if (dlgResult != MessageBoxResult.Yes)
            {
                return;
            }

            DeleteImagesSilent(vm);
        }

        private async void BtnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (mImages == null)
            {
                return;
            }

            var selectedImages = mImages.Where(x => x.Selected).ToArray();
            if (selectedImages.Length == 0)
            {
                // 请勾选要删除的截图
                MessageHelper.ShowByMsgId("CapturedImageUserControl.PleaseSelectImageToDelete");
                return;
            }

            // 确定要删除已勾选的 {0} 张截图吗？
            var msg = I18nHelper.Default.GetMessageWithArgs("CapturedImageUserControl.ConfirmDeleteImage", selectedImages.Length);
            var dlgResult = await MessageHelper.ShowYesNoAsync(msg);

            if (dlgResult != MessageBoxResult.Yes)
            {
                return;
            }

            DeleteImagesSilent(selectedImages);
        }

        private void DeleteImagesSilent(params ImageViewModel[] images)
        {
            try
            {
                // 删除的图片包含当前显示的图片的场合
                if (images.Any(x => x.Name == mCurrentImageName))
                {
                    ShowImage(null);
                }

                mExper.DeleteImages(images.Select(x => x.Name).ToList());
            }
            catch (Exception ex)
            {
                MessageHelper.ShowError(ex.Message);
            }
        }

        private void BuildImages(bool keepSelection)
        {
            var selectedImages = new HashSet<string>();
            if (mImages != null)
            {
                if (keepSelection)
                    selectedImages = mImages.Where(x => x.Selected).Select(x => x.Name).ToHashSet();
                mImages.ToList().ForEach(x => x.PropertyChanged -= Img_PropertyChanged);
            }
            var images = mExper.Images.Select(name =>
            {
                var img = new ImageViewModel(name)
                {
                    ImageFullPathProvider = mExper.GetImageFullPath,
                    Selected = selectedImages.Contains(name)
                };
                img.PropertyChanged += Img_PropertyChanged;
                return img;
            }).OrderBy(x => x.Name);
            mImages = new ObservableCollection<ImageViewModel>(images);
            IcImages.ItemsSource = mImages;
        }

        private bool _disableShowImage = false; // 如果为true，则即使选择改变也不预览图片
        private void Img_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (sender is not ImageViewModel vm)
                return;

            if (e.PropertyName == nameof(ImageViewModel.Selected))
            {
                if (_disableShowImage)
                    return;

                if (!vm.Selected)
                {
                    if (mCurrentImageName == vm.Name)
                        ShowImage(null);
                }
                else
                {
                    ShowImage(vm.Name);
                }
            }
        }

        private void BtnExport_Click(object sender, RoutedEventArgs e)
        {
            if (mImages == null)
            {
                return;
            }

            var selectedImages = mImages.Where(x => x.Selected).ToList();
            if (selectedImages.Count == 0)
            {
                // 请勾选要导出的截图
                MessageHelper.ShowByMsgId("CapturedImageUserControl.PleaseSelectImageToExport");
                return;
            }

            ExperManager.Default.ExportImages(mExper, selectedImages.Select(x => x.Name).ToList());
        }

        private void BtnClose_OnClick(object sender, RoutedEventArgs e)
        {
            CloseClicked?.Invoke(this, EventArgs.Empty);
        }

        private void ChkSelectUnSelectAll_CheckedChanged(object sender, RoutedEventArgs e)
        {
            if (mImages == null)
                return;

            _disableShowImage = true;
            var chked = ChkSelectUnSelectAll.IsChecked == true;
            mImages.ToList().ForEach(x => x.Selected = chked);
            _disableShowImage = false;

            if (!chked)
                ShowImage(null);
            else if (mImages.Count > 0)
                ShowImage(mImages.Last().Name);
        }
    }
}